package com.zmn.mcc.business.impl.dpermit.promotion;

import com.zmn.base.common.data.common.dro.marketing.account.MarketingAccountDRO;
import com.zmn.base.common.data.common.query.marketing.account.MarketingAccountQuery;
import com.zmn.base.common.data.dubbo.interfaces.marketing.account.MarketingAccountForeignRemoteService;
import com.zmn.base.plat.engine.common.constant.DubboConsts;
import com.zmn.base.plat.engine.common.constant.PlatEngineConsts;
import com.zmn.common.dto2.AMISListData;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.manager.common.database.annotation.ReadOnlyConnection;
import com.zmn.mcc.business.interfaces.dpermit.account.DpermitPromotionBService;
import com.zmn.mcc.common.constant.DpermitConsts;
import com.zmn.mcc.common.dto.exception.MccException;
import com.zmn.mcc.manager.utils.DpermitUtil;
import com.zmn.mcc.model.dto.dpermit.DpermitBaseDO;
import com.zmn.mcc.model.dto.dpermit.DpermitSimpleDO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.assertj.core.util.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author heguanghua
 * @since 2020/06/11 12:42
 */
@Service
public class DpermitPromotionBServiceImpl implements DpermitPromotionBService {
    protected Logger logger = LoggerFactory.getLogger(DpermitPromotionBServiceImpl.class);

    /**
     * 郭俏那边的合作
     */
    @DubboReference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private com.zmn.base.channel.dubbo.interfaces.channel.ChannelListRemoteService channelRemoteService;
    @DubboReference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private MarketingAccountForeignRemoteService marketingAccountForeignRemoteService;


    @Override
    @ReadOnlyConnection
    public List<DpermitSimpleDO> listPromotionDpermitChecked(Integer status, List<? extends DpermitBaseDO> dpermitIds) {

        List<DpermitSimpleDO> items = new ArrayList<>();

        List<DpermitSimpleDO> channelDROList = Lists.newArrayList();

        //已分配权限
        List<Integer> dpermitIdList = dpermitIds.stream().map(DpermitBaseDO::getDataId).collect(Collectors.toList());

        //合作id集合
        List<Integer> fourDpermitIdList = dpermitIds.stream().filter(e -> Objects.equals(DpermitConsts.PROMOTION_LEVEL_ONE, e.getDataLevel())).map(DpermitBaseDO::getDataId).collect(Collectors.toList());
        //二级合作
        List<com.zmn.base.channel.common.dro.ChannelDRO> twoCooperate = Lists.emptyList();
        com.zmn.base.channel.common.query.ChannelQuery channelQuery = new com.zmn.base.channel.common.query.ChannelQuery();
        channelQuery.setChannelIds(fourDpermitIdList);
        if (CollectionUtils.isNotEmpty(fourDpermitIdList)) {
            ResponseDTO<AMISListData<com.zmn.base.channel.common.dro.ChannelDRO>> cooperateDro = channelRemoteService.listByQueryFromAdmin(channelQuery);
            if (cooperateDro.isSuccess()) {
                twoCooperate = cooperateDro.getData().getItems();
            }
        }

        List<Integer> objectIdList = new ArrayList<>();
        //合作数据处理
        dealCooperate(channelDROList, twoCooperate, objectIdList);

        Map<Integer, List<DpermitSimpleDO>> accoutMap = new HashMap<>(16);
        //获取账户数据
        getAccountMap(accoutMap, objectIdList);

        for (DpermitSimpleDO simple : channelDROList) {

            // 防止数据错误抛出异常
            if (simple.getLevel() == null) {
                continue;
            }

            // 选中已分配
            if (CollectionUtil.isNotNullOrEmpty(dpermitIds) && dpermitIdList.contains(simple.getDataId())) {
                simple.setChecked(true);
            }

            // 合作的子集账户展示
            if (MapUtils.isNotEmpty(accoutMap) && CollectionUtils.isNotEmpty(accoutMap.get(simple.getDataId()))) {
                accoutMap.get(simple.getDataId()).forEach(e -> {
                    if (dpermitIdList.contains(e.getDataId())) {
                        e.setChecked(true);
                    }
                    simple.getSubors().add(e);
                });
            }
            // 合作加入主列表
            items.add(simple);
        }
        return items;
    }

    @Override
    public List<DpermitSimpleDO> listPromotionTreeAndDpermitChecked(Integer status, List<Integer> dpermitIds, List<Integer> account, Integer type) {

        List<DpermitSimpleDO> items = new ArrayList<>();

        // 组织ID和简单组织对象的映射关系
        Map<Integer, DpermitSimpleDO> map = new HashMap<>(16);
        Map<Integer, DpermitSimpleDO> subMap = new HashMap<>(16);


        List<DpermitSimpleDO> channelDROList = Lists.newArrayList();

        Map<Integer, List<DpermitSimpleDO>> accoutMap = new HashMap<>(16);

        //二级合作
        com.zmn.base.channel.common.query.ChannelQuery channelQuery = new com.zmn.base.channel.common.query.ChannelQuery();
        channelQuery.setChannelIds(dpermitIds);
        ResponseDTO<AMISListData<com.zmn.base.channel.common.dro.ChannelDRO>> amisListDataResponseDTO = channelRemoteService.listByQueryFromAdmin(channelQuery);
        if (!amisListDataResponseDTO.isSuccess() || CollectionUtil.isNullOrEmpty(amisListDataResponseDTO.getData().getItems())) {
            return Lists.emptyList();
        }

        List<com.zmn.base.channel.common.dro.ChannelDRO> twoCooperate = amisListDataResponseDTO.getData().getItems();

        List<Integer> objectIdList = new ArrayList<>();
        //合作数据处理
        dealCooperate(channelDROList, twoCooperate, objectIdList);
        if (CollectionUtils.isEmpty(objectIdList)) {
            throw new MccException("请先勾选上左边二级合作节点再勾选右边账户列表");
        }
        //获取账户数据
        getAccountMap(accoutMap, objectIdList);

        for (DpermitSimpleDO simple : channelDROList) {

            // 防止数据错误抛出异常
            if (simple.getLevel() == null) {
                continue;
            }

            // 简单组织对象
            map.put(simple.getDataId(), simple);

            // 选中已分配
            if (CollectionUtil.isNotNullOrEmpty(dpermitIds) && dpermitIds.contains(simple.getDataId())) {
                simple.setChecked(true);
            }

            items.add(simple);

            //添加合作时子集默认选中
            if (simple.getLevel() == DpermitConsts.PROMOTION_LEVEL_ONE && MapUtils.isNotEmpty(accoutMap)) {
                //添加合作按钮
                if (Objects.equals(2, type) && MapUtils.isNotEmpty(accoutMap) && CollectionUtils.isNotEmpty(accoutMap.get(simple.getDataId()))) {
                    accoutMap.get(simple.getDataId()).forEach(e -> e.setChecked(true));
                } else {
                    //不是添加合作时勾选账户
                    if (MapUtils.isNotEmpty(accoutMap) && CollectionUtils.isNotEmpty(accoutMap.get(simple.getDataId()))) {
                        accoutMap.get(simple.getDataId()).forEach(e -> {
                            if (account.contains(e.getDataId())) {
                                e.setChecked(true);
                            }
                        });
                    }
                }
                if (CollectionUtils.isNotEmpty(accoutMap.get(simple.getDataId()))) {
                    //二级节点
                    List<DpermitSimpleDO> fiveLevel = accoutMap.get(simple.getDataId()).stream()
                            .filter(e -> Objects.equals(DpermitConsts.PROMOTION_LEVEL_TWO, e.getLevel())).collect(Collectors.toList());
                    //三级节点
                    if (CollectionUtils.isNotEmpty(fiveLevel)) {
                        for (DpermitSimpleDO five : fiveLevel) {
                            List<DpermitSimpleDO> sixLevel = accoutMap.get(simple.getDataId()).stream()
                                    .filter(e -> Objects.equals(DpermitConsts.PROMOTION_LEVEL_THR, e.getLevel()) && e.getParentId() == five.getDataId())
                                    .collect(Collectors.toList());
                            if (CollectionUtils.isNotEmpty(sixLevel)) {
                                five.getSubors().addAll(sixLevel);
                            }
                        }
                    }
                    simple.getSubors().addAll(fiveLevel);
                }
            }
        }

        /**
         * 检查并处理简单数据对象选中状态
         * 下级部分选中则上级选中，下级全部选中则对上级标识
         */
        DpermitUtil.checkSelected(items, false);

        //合作默认选全部。不能不展示
        dealFour(items);

        return items;
    }

    /**
     * 处理合作下子节点
     *
     * @param items
     */
    private void dealFour(List<DpermitSimpleDO> items) {
        if (CollectionUtils.isNotEmpty(items)) {
            for (DpermitSimpleDO item : items) {
                if (item.getLevel() <= DpermitConsts.PROMOTION_LEVEL_TWO && CollectionUtils.isNotEmpty(item.getSubors()) && item.getSubors().stream().anyMatch(DpermitSimpleDO::isChecked)) {
                    item.setSubAll(false);
                } else {
                    item.setSubAll(true);
                }
                if (CollectionUtils.isNotEmpty(item.getSubors())) {
                    dealFour(item.getSubors());
                }
            }
        }
    }

    /**
     * 处理合作数据
     */
    private void dealCooperate(List<DpermitSimpleDO> channelDROList, List<com.zmn.base.channel.common.dro.ChannelDRO> twoCooperate, List<Integer> objectIdList) {
        for (com.zmn.base.channel.common.dro.ChannelDRO channelDRO : twoCooperate) {
            DpermitSimpleDO simple = new DpermitSimpleDO();
            simple.setDataId(channelDRO.getChannelId());
            simple.setDataName(channelDRO.getName());
            simple.setParentId(1);
            simple.setStatus(channelDRO.getStatus());
            //又在一级了
            simple.setLevel(DpermitConsts.PROMOTION_LEVEL_ONE);
            //合作id
            objectIdList.add(channelDRO.getChannelId());
            channelDROList.add(simple);
        }
    }

    /**
     * 处理账户
     */
    private void getAccountMap(Map<Integer, List<DpermitSimpleDO>> accoutMap, List<Integer> objectIdList) {
        if (CollectionUtils.isEmpty(objectIdList)) {
            return;
        }
        MarketingAccountQuery marketingAccountQuery = new MarketingAccountQuery();
        marketingAccountQuery.setCooperationIds(objectIdList);
        marketingAccountQuery.setStatus(PlatEngineConsts.STATUS_VALID);
        ResponseDTO<List<MarketingAccountDRO>> listByQuery = marketingAccountForeignRemoteService.listByQuery(marketingAccountQuery);
        if (listByQuery.isSuccess() && CollectionUtils.isNotEmpty(listByQuery.getData())) {
            List<MarketingAccountDRO> accountList = listByQuery.getData();
            Map<Integer, List<DpermitSimpleDO>> map = new HashMap<>(16);
            List<MarketingAccountDRO> marketingAccountDROS = accountList.stream().filter(e -> Objects.equals(GlobalConsts.NO, e.getLevel()) || Objects.equals(GlobalConsts.YES, e.getLevel())).collect(Collectors.toList());

            for (MarketingAccountDRO datum : marketingAccountDROS) {
                DpermitSimpleDO simple = new DpermitSimpleDO();
                simple.setDataId(datum.getAccountId());
                simple.setDataName(datum.getName());
                //一级账户父亲是合作，二级账户父亲是一级账户
                if (Objects.equals(GlobalConsts.NO, datum.getLevel())) {
                    simple.setParentId(datum.getCooperationId());
                    simple.setLevel(DpermitConsts.PROMOTION_LEVEL_TWO);
                } else {
                    simple.setParentId(datum.getParentAccountId() == null ? datum.getCooperationId() : datum.getParentAccountId());
                    simple.setLevel(DpermitConsts.PROMOTION_LEVEL_THR);
                }
                simple.setStatus(datum.getStatus());

                //根据合作id来区分账户
                if (CollectionUtils.isNotEmpty(accoutMap.get(datum.getCooperationId()))) {
                    accoutMap.get(datum.getCooperationId()).add(simple);
                } else {
                    List<DpermitSimpleDO> list = new ArrayList<>();
                    list.add(simple);
                    accoutMap.put(datum.getCooperationId(), list);
                }
            }
        }
    }

}
